package se.webbzon.boltzmann.battle.object.status;

import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;

import javax.media.j3d.Transform3D;
import javax.vecmath.Vector3d;

import se.webbzon.boltzmann.resource.Resources;
import se.webbzon.oschi01.worldarea.WorldArea;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;
import se.webbzon.oschi01.worldobject.appearance.Animation3D;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;
import se.webbzon.oschi01.worldobject.appearance.GroupAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.SimpleAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.TextAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.XYPlaneAppearance3D;

public class BattleStatusDamage extends WorldStaticObject {
	
	// The font of the damage text
	private static final Font damageFont = new Font("Arial",Font.PLAIN,8);
	
	// The remaining steps until destruction
	private int remaining;
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new battle status damage bubble. **/
	public BattleStatusDamage(int damage) {
		super(WorldObject.onStep,0,createAppearance(damage));
		setSize(2,2,1);
		setPosition(2,2.5,0);
		remaining = 30;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public void onStep(WorldArea world) {
		if (remaining == 0) {
			getGroup().removeInstance(this);
			world.destroyInstance(this);
		} else
			remaining--;
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	private static final Appearance3D createAppearance(int damage) {
		ArrayList<Appearance3D> appearances = new ArrayList<Appearance3D>();
		
		// Create the background
		XYPlaneAppearance3D background = 
				new XYPlaneAppearance3D(0,SimpleAppearance3D.TRANSPARENCY,false);
		background.setTextureSet(Resources.getTextureSet("buff_background"));
		background.setTextureIndex(3);
		background.setTransparency(0.2f);
		
		// Create the text
		TextAppearance3D text = 
				new TextAppearance3D(1,TextAppearance3D.LAYERS,damageFont,"" + damage);
		text.setLayer(0, 0, 1);
		Color dark, light;
		if (damage > 0) {
			dark = Color.red;
			light = new Color(255,48,48);
		} else {
			dark = Color.green;
			light = new Color(48,255,48);
		}
		text.setColor(dark);
		
		// Transform the text
		final Transform3D transform = new Transform3D();
		final Vector3d vector = new Vector3d(0.5,0.5,1);
		transform.setScale(vector);
		vector.set(0.1,0.1,0);
		transform.setTranslation(vector);
		text.setTransform(transform);
		
		appearances.add(background);
		appearances.add(text);
		GroupAppearance3D group = new GroupAppearance3D(appearances);
		group.setAnimation(new DamageAnimation(text,dark,light));
		return group;
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	private static class DamageAnimation implements Animation3D {

		// The shifting time
		private static final int shiftingTime = 2;
		
		// The text appearance associated with this animation
		private final TextAppearance3D text;
		
		// The dark and light color of the text
		private final Color dark, light;
		
		// Whatever the text if dark or light
		private boolean isDark;
		
		// The remaining time until color shift
		private int remaining;
		
		/*============================================================
		Constructors
		============================================================*/
		
		/** Creates a new damage animation. **/
		public DamageAnimation(TextAppearance3D text, Color dark, Color light) {
			this.text = text;
			this.dark = dark;
			this.light = light;
			remaining = shiftingTime;
			isDark = true;
		}
		
		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void onStepEnd(Appearance3D appearance) {
			if (remaining == 0) {
				if (isDark) {
					remaining = shiftingTime;
					text.setColor(light);
					isDark = false;
				} else {
					remaining = 2*shiftingTime;
					text.setColor(dark);
					isDark = true;
				}
			} else
				remaining--;
		}
		
	}

}
